package test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import main.FacadeDispatcher;
import main.FacadeTime;
import main.FacadeUnit;
import main.World;
import movement.Location;

import org.junit.Before;
import org.junit.Test;

import unit.Ambulance;
import unit.Garage;
import unit.PoliceCar;
import unit.Unit;
import dispatch.DispatchCenter;
import emergency.Emergency;
import emergency.Robbery;
import emergency.Severity;

public class useCaseTestReportUnitProblem {
	FacadeUnit facade1;
	FacadeDispatcher facade2;
	FacadeTime facade3;
	Location justALocation;
	
	DispatchCenter center;
	Garage garage;
	
	Emergency em1, em2, em3, em4;
	Unit u1,u2,u3;
	
	
	@Before
	public void setUp() throws Exception {
		center = new DispatchCenter("DC", new Location(0,0,"DCC"),new Location(5,0,"G"));
		garage = center.getGarage();
		
		String args[] = new String[1];
		args[0] = "environment.dat";
		World world = new World(args);
		world.setDispatchCenter(center);
		
		facade1 = new FacadeUnit(world);
		facade2 = new FacadeDispatcher(world);
		facade3 = new FacadeTime(world);
		
		garage = center.getGarage();
		justALocation = new Location(10,10,"NameDoesn'tMatter");
		
		em4 = new Robbery(justALocation, Severity.NORMAL, center, false, false);
		
		u1 = new PoliceCar("P1",100,center.getGarage());
		u2 = new PoliceCar("P2",120,center.getGarage());
		u3 = new PoliceCar("P3",130,center.getGarage());
	}
	
	@Test
	public void testReportUnitProblem() throws Exception{
		assertFalse(u1.isAssigned());
		assertFalse(u2.isAssigned());
		assertFalse(u3.isAssigned());
		
		assertEquals(em4.getStateName(),"staterecorded");
		
		facade2.assignAllUnits(em4);
		
		assertEquals(em4.getStateName(),"stateinprogress");
		assertFalse(u1.isAssigned());
		assertFalse(u2.isAssigned());
		assertTrue(u3.isAssigned());

		facade1.breakDown(u3);
		assertTrue(u3.isBroken());
		
		assertEquals(em4.getStateName(),"staterecorded");
		
		facade2.assignUnit(em4, u1);
		assertTrue(u1.isAssigned());
		
		facade3.simulatedTimeBy(10000);
		
		facade1.finishEmergency(u1);
		
		assertEquals("statecompleted", em4.getStateName());
	}
	
	@Test (expected=IllegalArgumentException.class)
	public void testReportUnitProblemAmbulanceBrokenDown() throws Exception{
		Unit u3 = new Ambulance("Ambulance", 200, center.getGarage());

		facade1.breakDown(u3);
	}
	
	@Test (expected=IllegalArgumentException.class)
	public void testReportUnitProblemTwiceBrokenDown() throws Exception{
		assertFalse(u1.isAssigned());
		assertFalse(u2.isAssigned());
		assertFalse(u3.isAssigned());
		
		assertEquals(em4.getStateName(),"staterecorded");
		
		facade2.assignAllUnits(em4);
		
		assertEquals(em4.getStateName(),"stateinprogress");
		assertFalse(u1.isAssigned());
		assertFalse(u2.isAssigned());
		assertTrue(u3.isAssigned());

		facade1.breakDown(u3);
		facade1.breakDown(u3);
	}
}
